﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Snake_DELALANDE_PELLEGRINI
{
    class Serpent
    {
        //TETE
        private Texture2D teteSerpent, teteSerpentDEBUG;
        private Vector2 originTete, originTeteBounds, tetePos, oldTetePos;
        private Rectangle boundsSerpent;
        private Params settings;
        private float RotationTete;
        private enum direction : int
        {
            Droite = 1,
            Gauche = 2,
            Haut = 3,
            Bas = 4
        };
        private direction laDirection;

        //CORPS
        private Texture2D corpsSerpent;
        private List<Vector2> corpsPos = new List<Vector2>();
        private List<Vector2> originCorps = new List<Vector2>();
        private List<Rectangle> boundsCorps = new List<Rectangle>();
        private Vector2 oldCorpsPos;

        //OTHERS
        private int maxSpeed, speedTimeout, deux, sizeSerpent/*, speedTimeout, score, oldSizeSerpent*/;
        private bool isDead;


        public Serpent(int joueur, ContentManager content)
        {
            //OTHERS
            settings = new Params();
            deux = 2;
            isDead = false;

            //TETE
            sizeSerpent = 100;

            maxSpeed = 2;
            speedTimeout = 200;
            //oldTetePos = 10;

            switch (joueur)
            {
                case 0:
                    laDirection = direction.Droite;
                    //teteSerpent = content.Load<Texture2D>("teteMAIN");
                    teteSerpent = content.Load<Texture2D>("teteMAIN-TEST");
                    corpsSerpent = content.Load<Texture2D>("corpsMAIN-2x2");
                    tetePos = new Vector2(50, (settings.screenHeight / 2));
                    boundsSerpent = new Rectangle((int)tetePos.X + teteSerpent.Width / 2, (int)tetePos.Y - teteSerpent.Height / 2, 25, 20);
                    originTeteBounds.X = tetePos.X + teteSerpent.Width / 2;
                    originTeteBounds.Y = tetePos.Y - teteSerpent.Height / 2;

                    break;
                case 1:
                    laDirection = direction.Gauche;
                    teteSerpent = content.Load<Texture2D>("teteMAIN-TEST");
                    corpsSerpent = content.Load<Texture2D>("corpsMAIN-2x2-ADV");
                    tetePos = new Vector2(settings.screenWidth - 50, settings.screenHeight / 2);
                    boundsSerpent = new Rectangle((int)tetePos.X - teteSerpent.Width / 2, (int)tetePos.Y - teteSerpent.Height / 2, 25, 20);
                    originTeteBounds.X = tetePos.X + teteSerpent.Width;
                    originTeteBounds.Y = tetePos.Y - teteSerpent.Height / 2;
                    break;
            }
            originTete.X = teteSerpent.Width / 2;
            originTete.Y = teteSerpent.Height / 2;

            teteSerpentDEBUG = content.Load<Texture2D>("teteDEBUG");

            //CORPS
            switch (joueur)
            {
                case 0:
                    for (int cpt = 0; cpt < sizeSerpent; cpt++)
                    {
                        corpsPos.Add(tetePos);
                        originCorps.Add(new Vector2(corpsSerpent.Width / 2, corpsSerpent.Height / 2));
                        boundsCorps.Add(new Rectangle((int)corpsPos[cpt].X, (int)corpsPos[cpt].Y, 2, 3));
                        deux++;
                    }
                    break;
                case 1:
                    for (int cpt = 0; cpt < sizeSerpent; cpt++)
                    {
                        corpsPos.Add(tetePos);
                        originCorps.Add(new Vector2(corpsSerpent.Width / 2, corpsSerpent.Height / 2));
                        boundsCorps.Add(new Rectangle((int)corpsPos[cpt].X, (int)corpsPos[cpt].Y, 2, 2));
                        deux++;
                    }
                    break;
            }
        }

        public void setDefaultPosition(int joueur)
        {
            //CLEANING CORPS
            corpsPos.RemoveRange(0, sizeSerpent);
            originCorps.RemoveRange(0, sizeSerpent);
            boundsCorps.RemoveRange(0, sizeSerpent);

            //OTHERS
            deux = 2;
            isDead = false;

            //TETE
            sizeSerpent = 100;

            maxSpeed = 2;
            speedTimeout = 200;
            
            switch (joueur)
            {
                case 0:
                    laDirection = direction.Droite;
                    tetePos = new Vector2(50, (settings.screenHeight / 2));
                    boundsSerpent = new Rectangle((int)tetePos.X + teteSerpent.Width / 2, (int)tetePos.Y - teteSerpent.Height / 2, 25, 20);
                    originTeteBounds.X = tetePos.X + teteSerpent.Width / 2;
                    originTeteBounds.Y = tetePos.Y - teteSerpent.Height / 2;
                    break;
                case 1:
                    laDirection = direction.Gauche;
                    tetePos = new Vector2(settings.screenWidth - 50, settings.screenHeight / 2);
                    boundsSerpent = new Rectangle((int)tetePos.X - teteSerpent.Width / 2, (int)tetePos.Y - teteSerpent.Height / 2, 25, 20);
                    originTeteBounds.X = tetePos.X + teteSerpent.Width;
                    originTeteBounds.Y = tetePos.Y - teteSerpent.Height / 2;
                    break;
            }
            originTete.X = teteSerpent.Width / 2;
            originTete.Y = teteSerpent.Height / 2;

            //CORPS
            switch (joueur)
            {
                case 0:
                    for (int cpt = 0; cpt < sizeSerpent; cpt++)
                    {
                        corpsPos.Add(tetePos);
                        originCorps.Add(new Vector2(corpsSerpent.Width / 2, corpsSerpent.Height / 2));
                        boundsCorps.Add(new Rectangle((int)corpsPos[cpt].X, (int)corpsPos[cpt].Y, 2, 3));
                        deux++;
                    }
                    break;
                case 1:
                    for (int cpt = 0; cpt < sizeSerpent; cpt++)
                    {
                        corpsPos.Add(tetePos);
                        originCorps.Add(new Vector2(corpsSerpent.Width / 2, corpsSerpent.Height / 2));
                        boundsCorps.Add(new Rectangle((int)corpsPos[cpt].X, (int)corpsPos[cpt].Y, 2, 2));
                        deux++;
                    }
                    break;
            }
        }

        public void MoveTo(String newDirection)
        {
            if (maxSpeed != 2)
            {
                if (speedTimeout <= 0)
                {
                    maxSpeed = 2;
                    speedTimeout = 200;
                }
                else
                {
                    speedTimeout--;
                }
            }
            for (int speed = 0; speed <= maxSpeed; speed++)
            {
                oldTetePos = tetePos;

                switch (newDirection)
                {
                    case "D":
                        laDirection = direction.Droite;
                        tetePos = new Vector2((int)tetePos.X + 1, (int)tetePos.Y);
                        //tetePos.X += 1;
                        RotationTete = MathHelper.Pi * 2;
                        boundsSerpent = new Rectangle((int)tetePos.X + teteSerpent.Width / 10, (int)tetePos.Y - teteSerpent.Height / 2, 20, 20);
                        break;
                    case "G":
                        laDirection = direction.Gauche;
                        tetePos = new Vector2((int)tetePos.X - 1, (int)tetePos.Y);
                        //tetePos.X -= 1;
                        RotationTete = MathHelper.Pi;
                        boundsSerpent = new Rectangle((int)tetePos.X - teteSerpent.Width / 2, (int)tetePos.Y - teteSerpent.Height / 2, 20, 20);
                        break;
                    case "H":
                        laDirection = direction.Haut;
                        tetePos = new Vector2((int)tetePos.X, (int)tetePos.Y - 1);
                        //tetePos.Y -= 1;
                        RotationTete = -MathHelper.Pi / 2;
                        boundsSerpent = new Rectangle((int)tetePos.X - teteSerpent.Height / 2, (int)tetePos.Y - teteSerpent.Width / 2, 20, 20);
                        break;
                    case "B":
                        laDirection = direction.Bas;
                        tetePos = new Vector2((int)tetePos.X, (int)tetePos.Y + 1);
                        //tetePos.Y += 1;
                        RotationTete = MathHelper.Pi / 2;
                        boundsSerpent = new Rectangle((int)tetePos.X - teteSerpent.Height / 2, (int)tetePos.Y + teteSerpent.Width / 10, 20, 20);
                        break;
                }

                for (int cpt = 0; cpt < sizeSerpent; cpt++)
                {
                    oldCorpsPos = corpsPos[cpt];
                    corpsPos[cpt] = oldTetePos;
                    oldTetePos = oldCorpsPos;

                    boundsCorps[cpt] = new Rectangle((int)corpsPos[cpt].X, (int)corpsPos[cpt].Y, 1, 3);
                }
            }
        }

        public bool collisionWithScreen()
        {
            //GAUCHE ECRAN
            if (boundsSerpent.X <= 0 && laDirection == direction.Gauche) { return true; }
            //DROITE ECRAN
            else if (boundsSerpent.X >= (settings.screenWidth - teteSerpent.Width / 2) && laDirection == direction.Droite) { return true; }
            //HAUT ECRAN
            else if (boundsSerpent.Y <= 0 && laDirection == direction.Haut) { return true; }
            //BAS ECRAN
            else if (boundsSerpent.Y >= (settings.screenHeight - teteSerpent.Width / 2) && laDirection == direction.Bas) { return true; }
            else { return false; }
        }

        public bool collisionWithBody()
        {
            for (int cpt = 0; cpt < corpsPos.Count; cpt++)
            {
                if (boundsSerpent.Intersects(boundsCorps[cpt]))
                {
                    return true;
                }
            }
            return false;
        }

        public void Grandir(int size)
        {
            for (int cpt = 0; cpt < size; cpt++)
            {
                corpsPos.Add(new Vector2(corpsPos[sizeSerpent - 1].X, corpsPos[sizeSerpent - 1].Y));
                originCorps.Add(new Vector2(corpsSerpent.Width / 2, corpsSerpent.Height / 2));
                boundsCorps.Add(new Rectangle((int)corpsPos[sizeSerpent].X, (int)corpsPos[sizeSerpent].Y, 1, 3));
                sizeSerpent++;
            }
        }

        public void Shrink(int size)
        {
            if (sizeSerpent - size >= 20)
            {
                corpsPos.RemoveRange(sizeSerpent - size, size);
                originCorps.RemoveRange(sizeSerpent - size, size);
                boundsCorps.RemoveRange(sizeSerpent - size, size);
                sizeSerpent -= size;
            }
        }

        // TETE SERPENT GET
        public Vector2 getOriginHead()
        {
            return originTete;
        }

        public Vector2 getPositionHead()
        {
            return tetePos;
        }

        public float getRotationHead()
        {
            return RotationTete;
        }

        public Rectangle getBoundsHead()
        {
            return boundsSerpent;
        }

        public Texture2D drawTeteSerpent()
        {
            return teteSerpent;
        }

        public Texture2D drawTeteSerpentDEBUG()
        {
            return teteSerpentDEBUG;
        }
        //------------------------------

        // CORPS SERPENT GET
        public Vector2 getPositionCorps(int index)
        {
            return corpsPos[index];
        }

        public Vector2 getOriginCorps(int index)
        {
            return originCorps[index];
        }

        public Rectangle getBoundsCorps(int index)
        {
            return boundsCorps[index];
        }

        public Texture2D drawCorpsSerpent()
        {
            return corpsSerpent;
        }
        //------------------------------

        public void setMaxSpeed(int newSpeed)
        {
            maxSpeed = newSpeed;
            speedTimeout = 200;
        }

        public int getMaxSpeed()
        {
            return maxSpeed;
        }

        public void setIsDead(bool dead)
        {
            isDead = dead;
        }

        public bool getIsDead()
        {
            return isDead;
        }

        public int getSize()
        {
            return sizeSerpent;
        }

    }
}
